﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using thinger.ModbusLib;

namespace thinger.ModbusProject
{
    public partial class FrmMain : Form
    {
        private ModbusRTU modbusRTU = new ModbusRTU();

        // 创建多线程的标志位
        private CancellationTokenSource cts;

        public FrmMain()
        {
            InitializeComponent();

            // 端口号
            this.cb_prot.DataSource = SerialPort.GetPortNames();

            // 波特率
            this.cb_BaudRate.Items.AddRange(new string[] { "2400", "4800", "9600" });

            this.cb_BaudRate.SelectedIndex = 2;
        }

        private void btn_Connect_Click(object sender, EventArgs e)
        {
            bool isConnect = modbusRTU.Connect(this.cb_prot.Text, int.Parse(cb_BaudRate.Text), Parity.None, 8, StopBits.One);

            MessageBox.Show(isConnect ? "连接成功" : "连接失败", "建立连接");

            // 开个子线程,持续读取
            if (isConnect)
            {
                cts = new CancellationTokenSource();

                Task.Run(new Action(() =>
                {
                    Communication();
                }), cts.Token);
            }
        }

        private void btn_DisConnect_Click(object sender, EventArgs e)
        {
            // 取消多线程
            // ?.:这里用?.是因为没有建立连接时,cts=null,确保不报错
            cts?.Cancel();

            Thread.Sleep(100);

            // 断开连接
            modbusRTU.DisConnect();
        }

        private void Communication()
        {
            while (!cts.IsCancellationRequested)
            {

                // 读取1号站点,从0开始的两个寄存器
                byte[] data = modbusRTU.ReadOutputRegisters(1, 0, 2);
                if (data != null && data.Length == 4)
                {
                    // 跨线程不能访问winform控件,需要使用this.Invoke
                    this.Invoke(new Action(() =>
                    {
                        this.lbl_Humidit.Text = ((data[0] * 256 + data[1]) * 0.1f).ToString();
                        this.lbl_Temp.Text = ((data[2] * 256 + data[3]) * 0.1f).ToString();

                    }));

                }

                Thread.Sleep(100);
            }
        }

        private void btnStopWatch_Click(object sender, EventArgs e)
        {
            //取消多线程
            cts?.Cancel();
        }
    }
}
